<template>
    <view class="da-tree" :style="{'--theme-color': themeColor}">
        <scroll-view class="da-tree-scroll" :scroll-y="true" :scroll-x="false">
            <view class="da-tree-item" :class="{'is-show': item.show}"
                :style="{paddingLeft: item.level * indent + 'rpx'}" v-for="item in datalist" :key="item.key">
                <view v-if="item.showArrow" class="da-tree-item__icon" @click="handleExpandedChange(item)">
                    <view :class="['da-tree-item__icon--arr','is-loading']" v-if="loadLoading && item.loading"></view>
                    <view :class="['da-tree-item__icon--arr','is-expand', {'is-right':!item.expand}]" v-else></view>
                </view>
                <view v-else class="da-tree-item__icon"></view>
                <view class="da-tree-item__checkbox"
                    :class="[`da-tree-item__checkbox--${checkboxPlacement}`,{'is--disabled': item.disabled}]"
                    v-if="showCheckbox" @click="handleCheckChange(item)">
                    <view class="da-tree-item__checkbox--icon da-tree-checkbox-checked"
                        v-if="item.checkedStatus === isCheckedStatus"></view>
                    <view class="da-tree-item__checkbox--icon da-tree-checkbox-indeterminate"
                        v-else-if="item.checkedStatus === halfCheckedStatus"></view>
                    <view class="da-tree-item__checkbox--icon da-tree-checkbox-outline" v-else></view>
                </view>
                <view class="da-tree-item__checkbox"
                    :class="[`da-tree-item__checkbox--${checkboxPlacement}`,{'is--disabled': item.disabled}]"
                    v-if="!showCheckbox && showRadioIcon" @click="handleRadioChange(item)">
                    <view class="da-tree-item__checkbox--icon da-tree-radio-checked"
                        v-if="item.checkedStatus === isCheckedStatus"></view>
                    <view class="da-tree-item__checkbox--icon da-tree-radio-indeterminate"
                        v-else-if="item.checkedStatus === halfCheckedStatus"></view>
                    <view class="da-tree-item__checkbox--icon da-tree-radio-outline" v-else></view>
                </view>
                <view class="da-tree-item__label" :class="'da-tree-item__label--'+item.checkedStatus"
                    @click="handleLabelClick(item)">
                    {{ item.label }}
                    <text class="da-tree-item__label--append" v-if="item.append">{{ item.append }}</text>
                </view>
            </view>
        </scroll-view>
    </view>
</template>

<script>
    import {
        unCheckedStatus,
        halfCheckedStatus,
        isCheckedStatus,
        deepClone,
        getAllNodeKeys,
        getAllNodes,
        logError,
        isArray,
        isString,
        isNumber,
        isFunction,
    } from './utils'
    import basicProps from './props'

    export default {
        name: 'DaTree',
        props: basicProps,
        data() {
            return {
                unCheckedStatus,
                halfCheckedStatus,
                isCheckedStatus,
                /** 原始的树数据 */
                dataRef: [],
                /** 处理后的一维树项数据 */
                datalist: [],
                /** 处理后的以key为键值的树项数据 */
                datamap: {},
                /** 默认的展开数据 */
                expandedKeys: [],
                /** 默认的已选数据 */
                checkedKeys: null,
                /** 加载状态 */
                loadLoading: false,
                fieldMap: {
                    value: 'value',
                    label: 'label',
                    children: 'children',
                    disabled: 'disabled',
                    append: 'append',
                    leaf: 'leaf',
                    sort: 'sort',
                },
            }
        },
        watch: {
            defaultExpandedKeys: {
                // deep: true,
                immediate: true,
                handler: function(v) {
                    if (v?.length) {
                        this.expandedKeys = v
                    } else {
                        this.expandedKeys = []
                    }

                    // if (v) this.checkInitData(this.datalist)
                },
            },
            defaultCheckedKeys: {
                // deep: true,
                immediate: true,
                handler: function(v) {
                    if (this.showCheckbox) {
                        if (v?.length) {
                            this.checkedKeys = v
                        } else {
                            this.checkedKeys = []
                        }
                    } else {
                        if (v || v === 0) {
                            this.checkedKeys = v
                        } else {
                            this.checkedKeys = null
                        }
                    }
                    // this.checkInitData(this.datalist)
                },
            },
            data: {
                deep: true,
                immediate: true,
                handler: function(v) {
                    this.dataRef = deepClone(v)
                    setTimeout(() => {
                        this.initData()
                    }, 36)
                },
            },
        },
        methods: {
            /**
             * 初始化数据结构
             */
            initData() {
                this.fieldMap = {
                    value: this.field?.key || this.field?.value || this.valueField || 'value',
                    label: this.field?.label || this.labelField || 'label',
                    children: this.field?.children || this.childrenField || 'children',
                    disabled: this.field?.disabled || this.disabledField || 'disabled',
                    append: this.field?.append || this.appendField || 'append',
                    leaf: this.field?.leaf || this.leafField || 'leaf',
                    sort: this.field?.sort || this.sortField || 'sort',
                }

                const data = deepClone(this.dataRef)
                this.datalist = []
                this.datamap = {}

                // clean tree
                this.handleTreeData(data)
                // flat tree
                this.datalist = this.checkInitData(this.datalist)

                console.log('init datalist', this.datalist)
                console.log('init datamap', this.datamap)
            },

            /**
             * 转换为节点数据
             * @param data
             * @param parent
             * @param level
             */
            handleTreeData(data = [], parent = null, level = 0, insertIndex = -1) {
                return data.reduce((prev, cur, index) => {
                    const key = cur[this.fieldMap.value]
                    const children = cur[this.fieldMap.children] || null
                    const newItem = this.createNewItem(cur, index, parent, level)
                    if (insertIndex > -1) {
                        // 插入子项尾部
                        const index = (parent.childrenKeys?.length || 0) + insertIndex + 1
                        if (!parent?.childrenKeys?.includes(key)) {
                            this.datamap[key] = newItem
                            this.datalist.splice(index, 0, newItem)
                            parent.children.push(newItem)
                            if (newItem.parentKeys?.length) {
                                newItem.parentKeys.forEach(k => {
                                    this.datamap[k].childrenKeys = [...this.datamap[k].childrenKeys,
                                        newItem.key
                                    ]
                                })
                            }
                        }
                    } else {
                        this.datamap[key] = newItem
                        this.datalist.push(newItem)
                    }

                    const hasChildren = children && children.length > 0
                    if (hasChildren) {
                        const childrenData = this.handleTreeData(children, newItem, level + 1)
                        // childrenData.sort((a, b) => a.sort - b.sort)
                        newItem.children = childrenData
                        const childrenKeys = childrenData.reduce((p, k) => {
                            const keys = k.childrenKeys
                            p.push(...keys, k.key)
                            return p
                        }, [])
                        newItem.childrenKeys = childrenKeys
                    }
                    prev.push(newItem)
                    return prev
                }, [])
            },

            /**
             * 创建节点
             * @param item
             * @param index
             * @param parent
             * @param level
             */
            createNewItem(item, index, parent, level) {
                const key = item[this.fieldMap.value]
                const label = item[this.fieldMap.label]
                const sort = item[this.fieldMap.sort] || 0
                const children = item[this.fieldMap.children] || null
                const append = item[this.fieldMap.append] || null
                let disabled = item[this.fieldMap.disabled] || false
                // 优先继承父级禁用属性
                disabled = parent?.disabled || disabled
                let isLeaf = isFunction(this.isLeafFn) ? this.isLeafFn(item) : (item[this.fieldMap.leaf] || false)
                // const hasChildren = children && children.length > 0
                const isEmptyChildren = children && children.length === 0
                let showArrow = true
                // let isLeaf = !hasChildren
                let expand = this.defaultExpandAll || false
                // 是否异步加载模式
                const isLoadMode = this.loadMode && isFunction(this.loadApi)

                if (!children) {
                    expand = false
                    if (isLoadMode) {
                        showArrow = true
                    } else {
                        isLeaf = true
                        showArrow = false
                    }
                }

                if (isEmptyChildren) {
                    expand = false
                    if (isLoadMode) {
                        showArrow = true
                    } else {
                        isLeaf = true
                        showArrow = false
                    }
                }

                if (isLeaf) {
                    showArrow = false
                    expand = false
                } else {
                    showArrow = true
                }

                // onlyRadioLeaf 单选只能选择末级节点
                if (!this.showCheckbox) {
                    if (this.onlyRadioLeaf) {
                        if (!isLeaf) {
                            disabled = true
                        } else {
                            // 仍旧继承父类原始禁用状态
                            disabled = parent?.originItem?.disabled || false
                        }
                    }
                }

                if (disabled) {
                    if (isLeaf || !children || isEmptyChildren) {
                        expand = false
                        showArrow = false
                    }
                }

                const parentKey = parent ? parent.key : null
                const show = this.defaultExpandAll || level === 0

                const newItem = {
                    key,
                    parentKey,
                    label,
                    append,
                    isLeaf,
                    showArrow,
                    level,
                    expand,
                    show,
                    sort,
                    disabled,
                    loaded: false,
                    loading: false,
                    indexs: [index],
                    checkedStatus: unCheckedStatus,
                    parentKeys: [],
                    childrenKeys: [],
                    children: [],
                    originItem: item,
                }

                if (parent) {
                    newItem.parentKeys = [parent.key, ...parent.parentKeys]
                    newItem.indexs = [...parent.indexs, index]
                }

                return newItem
            },

            /**
             * 处理初始化内容
             * @param list
             */
            checkInitData(list) {
                let checkedKeyList = null
                let expandedKeyList = []
                if (this.showCheckbox) {
                    checkedKeyList = [...new Set(this.checkedKeys || [])]
                    expandedKeyList = this.expandChecked ? ([...(this.checkedKeys || []), ...(this.expandedKeys ||
                    [])]) : this.expandedKeys
                } else {
                    checkedKeyList = this.checkedKeys || null
                    expandedKeyList = this.expandChecked && this.checkedKeys ? ([this.checkedKeys, ...(this
                        .expandedKeys || [])]) : this.expandedKeys
                }

                this.handleCheckState(list, checkedKeyList, true)

                // 处理初始展开
                expandedKeyList = [...new Set(expandedKeyList)]
                if (!this.defaultExpandAll) {
                    this.handleExpandState(list, expandedKeyList, true)
                }

                list.sort((a, b) => {
                    if (a.sort === 0 && b.sort === 0) {
                        return 0
                    }

                    if (a.parentKey === b.parentKey) {
                        if (a.sort - b.sort > 0) {
                            return 1
                        } else {
                            return -1
                        }
                    }

                    return 0
                })

                return list
            },

            /**
             * 处理选中
             * @param list
             * @param checkedKeyList
             */
            handleCheckState(list, checkedKeyList, checked = true) {
                // 多选
                if (this.showCheckbox) {
                    if (checkedKeyList?.length) {
                        checkedKeyList.forEach(k => {
                            const item = this.datamap[k]
                            if (item) {
                                this.checkTheChecked(item, checked)
                            }
                        })
                    }

                    return
                }

                // 单选
                for (let i = 0; i < list.length; i++) {
                    const item = list[i]
                    if (item.key === checkedKeyList) {
                        // console.log('item.key === checkedKeyList', item.key, checkedKeyList)
                        this.checkTheRadio(item, checked)
                        break
                    }
                }
            },

            /**
             * 校验多选节点
             * @param item
             * @param checked
             */
            checkTheChecked(item, checked = true) {
                const { childrenKeys, parentKeys, disabled = false } = item
                if (!this.checkedDisabled && disabled) return

                // 当前
                item.checkedStatus = checked ? isCheckedStatus : unCheckedStatus

                if (!this.checkStrictly) {
                    // 子类
                    childrenKeys.forEach(k => {
                        const childrenItem = this.datamap[k]
                        childrenItem.checkedStatus = (!this.checkedDisabled && childrenItem.disabled) ?
                            childrenItem.checkedStatus : item.checkedStatus
                    })

                    // 父类
                    parentKeys.forEach(k => {
                        const parentItem = this.datamap[k]
                        parentItem.checkedStatus = this.getParentCheckedStatus(parentItem)
                    })
                }
            },

            /**
             * 校验单选节点
             * @param item
             */
            checkTheRadio(item, checked) {
                const { parentKeys, isLeaf, disabled = false } = item
                if (!this.checkedDisabled && disabled) return

                // 限制末节点选中，但当前非末节点
                if (this.onlyRadioLeaf && !isLeaf) {
                    logError(`限制了末节点选中，当前[${item.label}]非末节点`)
                    return
                }

                if (this.datalist?.length) {
                    this.datalist.forEach(k => {
                        k.checkedStatus = unCheckedStatus
                    })
                }
                console.log('000', item, parentKeys, this.datamap)

                parentKeys.forEach(k => {
                    console.log('kkk', k, this.datamap[k])
                    const parentItem = this.datamap[k]
                    parentItem.checkedStatus = checked ? this.getParentCheckedStatus(parentItem) :
                        unCheckedStatus
                })

                // 当前
                item.checkedStatus = checked ? isCheckedStatus : unCheckedStatus
            },

            /**
             * 处理父节点展开
             * @param item
             * @param expand
             */
            // handleExpandParentNode(item, expand = true) {
            //   if (!expand) return

            //   if (item?.parentKeys?.length) {
            //     item.parentKeys.forEach(pk => {
            //       if (!this.datamap[pk].expand) {
            //         this.datamap[pk].expand = true
            //       }
            //     })
            //   }
            // },

            /**
             * 处理节点展开
             * @param list
             * @param expandedKeyList
             * @param expand
             */
            handleExpandState(list, expandedKeyList, expand = true) {
                // 收起
                if (expand === false) {
                    for (let i = 0; i < list.length; i++) {
                        const item = list[i]
                        if (expandedKeyList?.includes(item.key)) {
                            item.expand = false
                            if (item.childrenKeys?.length) {
                                item.childrenKeys.forEach(ck => {
                                    this.datamap[ck].expand = false
                                    this.datamap[ck].show = false
                                })
                            }
                        }
                    }
                    return
                }
                // 展开
                for (let i = 0; i < list.length; i++) {
                    const item = list[i]
                    // 处理展开
                    if (expandedKeyList?.includes(item.key)) {
                        // 父子
                        item.expand = true
                        if (item.children?.length) {
                            item.children.forEach(k => {
                                const kItem = this.datamap[k.key]
                                kItem.show = true
                            })
                        }

                        // 族系
                        if (item.parentKeys?.length) {
                            item.parentKeys.forEach(k => {
                                const kItem = this.datamap[k]
                                kItem.expand = true
                                if (kItem.children?.length) {
                                    kItem.children.forEach(k => {
                                        const skItem = this.datamap[k.key]
                                        skItem.show = true
                                    })
                                }
                            })
                        }
                    }
                }
            },

            /**
             * 点击选框
             * @param item
             */
            handleCheckChange(item) {
                const { childrenKeys, parentKeys, checkedStatus, isLeaf, disabled = false } = item
                if (!this.showCheckbox) return
                if (disabled) return

                // 当前
                item.checkedStatus = checkedStatus === isCheckedStatus ? unCheckedStatus : isCheckedStatus

                // 子类
                if (!this.checkStrictly) {
                    if (this.expandChecked) {
                        item.show = true
                        item.expand = childrenKeys?.length > 0 || isLeaf
                    }

                    childrenKeys.forEach(k => {
                        const childrenItem = this.datamap[k]
                        childrenItem.checkedStatus = childrenItem.disabled ? childrenItem.checkedStatus : item
                            .checkedStatus

                        if (this.expandChecked) {
                            childrenItem.show = true
                            childrenItem.expand = childrenItem?.childrenKeys?.length > 0 || childrenItem.isLeaf
                        }
                    })
                } else {
                    if (this.expandChecked) {
                        logError(`多选时，当 checkStrictly 为 true 时，不支持选择自动展开子节点属性(expandChecked)`)
                    }
                }

                // 父类
                if (!this.checkStrictly) {
                    parentKeys.forEach(k => {
                        const parentItem = this.datamap[k]
                        parentItem.checkedStatus = this.getParentCheckedStatus(parentItem)
                    })
                }

                const hasCheckedKeys = []
                for (let i = 0; i < this.datalist.length; i++) {
                    const k = this.datalist[i]
                    if (k.checkedStatus === isCheckedStatus) {
                        if ((this.packDisabledkey && k.disabled) || !k.disabled) {
                            hasCheckedKeys.push(k.key)
                        }
                    }
                }

                this.checkedKeys = [...hasCheckedKeys]

                this.$emit('change', hasCheckedKeys, item)
            },

            /**
             * 点击单选
             * @param item
             */
            handleRadioChange(item) {
                const { parentKeys, checkedStatus, key, disabled = false, isLeaf } = item
                if (this.showCheckbox) return
                if (this.onlyRadioLeaf && !isLeaf) this.handleExpandedChange(item)

                if (disabled) return

                // 重置所有选择
                if (this.datalist?.length) {
                    for (let i = 0; i < this.datalist.length; i++) {
                        const k = this.datalist[i]
                        k.checkedStatus = unCheckedStatus
                    }
                }

                parentKeys.forEach(k => {
                    const parentItem = this.datamap[k]
                    parentItem.checkedStatus = this.getParentCheckedStatus(parentItem)
                })

                // 当前
                item.checkedStatus = checkedStatus === isCheckedStatus ? unCheckedStatus : isCheckedStatus

                this.checkedKeys = key
                this.$emit('change', key, item)
            },

            /**
             * 点击标签
             */
            handleLabelClick(item) {
                if (this.showCheckbox) {
                    this.handleCheckChange(item)
                } else {
                    this.handleRadioChange(item)
                }
            },

            /**
             * 点击展开收起
             * @param item
             */
            async handleExpandedChange(item) {
                const { expand, loading = false, disabled } = item
                if (this.loadLoading && loading) return

                this.checkExpandedChange(item)

                // 异步
                item.expand = !expand

                let currentItem = null
                if (!disabled) {
                    if (!this.showCheckbox && this.onlyRadioLeaf && this.loadMode) {
                        logError(`单选时，当 onlyRadioLeaf 为 true 时不支持动态数据`)
                    } else {
                        currentItem = await this.loadExpandNode(item)
                    }
                }

                this.$emit('expand', !expand, currentItem || item || null)
            },

            /**
             * 检查展开状态
             * @param item
             */
            checkExpandedChange(item) {
                const { expand, childrenKeys, children = null } = item

                if (expand) {
                    if (childrenKeys?.length) {
                        childrenKeys.forEach(k => {
                            if (this.datamap[k]) {
                                this.datamap[k].show = false
                                this.datamap[k].expand = false
                            }
                        })
                    }
                } else {
                    if (children?.length) {
                        const childrenKeys = children.map(k => k.key)
                        childrenKeys.forEach(k => {
                            if (this.datamap[k]) {
                                this.datamap[k].show = true
                            }
                        })
                    }
                }
            },

            /**
             * 加载异步数据
             * @param item
             */
            async loadExpandNode(item) {
                const { expand, key, loaded, children } = item
                if (children?.length && !this.alwaysFirstLoad) {
                    return item
                }

                if (expand && this.loadMode && !loaded) {
                    if (isFunction(this.loadApi)) {
                        this.expandedKeys.push(key)
                        this.loadLoading = true
                        item.loading = true

                        const currentNode = deepClone(item)
                        const apiRes = await this.loadApi(currentNode)

                        // 新增子项
                        let newChildren = [...(item.originItem?.children || []), ...(apiRes || [])]
                        const newChildrenObj = {}
                        newChildren = newChildren.reduce((total, next) => {
                            newChildrenObj[next[this.fieldMap]] ? '' : newChildrenObj[next[this.fieldMap]] =
                                true && total.push(next)
                            return total
                        }, [])

                        item.originItem.children = newChildren || null
                        if (apiRes?.length) {
                            const insertIndex = this.datalist.findIndex(k => k.key === item.key)
                            this.handleTreeData(apiRes, item, item.level + 1, insertIndex)
                            this.datalist = this.checkInitData(this.datalist)
                        } else {
                            // 加载后无数据就移除展开图标
                            item.expand = false
                            item.isLeaf = true
                            item.showArrow = false
                        }

                        this.loadLoading = false
                        item.loading = false
                        item.loaded = true
                    }
                } else {
                    const eki = this.expandedKeys.findIndex(k => k === key)
                    if (eki >= 0) {
                        this.expandedKeys.splice(eki, 1)
                    }
                }

                return item
            },

            /**
             * 获取父类的选中状态
             * @param item
             */
            getParentCheckedStatus(item) {
                if (!item) {
                    return unCheckedStatus
                }

                if (!this.checkedDisabled && item.disabled) {
                    return item.checkedStatus || unCheckedStatus
                }

                // 单选时，父类永远为半选
                if (!this.showCheckbox) {
                    return halfCheckedStatus
                }

                const { children } = item
                // 子类全选中
                const childrenCheckedAll = children.every(k => k.checkedStatus === isCheckedStatus)
                if (childrenCheckedAll) {
                    return isCheckedStatus
                }

                // 子类全不选中
                const childrenUncheckedAll = children.every(k => k.checkedStatus === unCheckedStatus)
                if (childrenUncheckedAll) {
                    return unCheckedStatus
                }

                return halfCheckedStatus
            },
            /**
             * 返回已选的 key
             */
            getCheckedKeys() {
                return getAllNodeKeys(this.datalist, 'checkedStatus', isCheckedStatus, this.packDisabledkey)
            },
            /**
             * 根据key设置已选
             * @param keys 多选时为key的数组，单选时为key
             * @param checked 多选时为key的数组，单选时为key
             */
            setCheckedKeys(keys, checked = true) {
                // 多选
                if (this.showCheckbox) {
                    if (!isArray(keys)) {
                        logError(`setCheckedKeys 第一个参数非数组，传入的是[${keys}]`)
                        return
                    }

                    const list = this.datalist

                    // 取消选择
                    if (checked === false) {
                        let newCheckedKeys = []
                        for (let i = 0; i < this.checkedKeys.length; i++) {
                            const ck = this.checkedKeys[i]
                            if (!keys.includes(ck)) {
                                newCheckedKeys.push(ck)
                            }
                        }
                        newCheckedKeys = [...new Set(newCheckedKeys)]
                        this.checkedKeys = newCheckedKeys
                        this.handleCheckState(list, keys, false)

                        return
                    }

                    // 选择
                    const newCheckedKeys = [...this.checkedKeys, ...keys]
                    this.checkedKeys = [...new Set(newCheckedKeys)]
                    this.handleCheckState(list, this.checkedKeys, true)

                    if (this.expandChecked && checked) {
                        this.expandedKeys = [...new Set([...(this.checkedKeys || []), ...(keys || [])])]
                        this.handleExpandState(list, keys, true)
                    }
                    return
                }

                // 单选
                // 如果为数组则拿第一个
                if (isArray(keys)) {
                    keys = keys[0]
                }

                if (!isString(keys) && !isNumber(keys)) {
                    logError('setCheckedKeys 第一个参数字符串或数字，传入的是==>', keys)
                    return
                }

                const list = this.datalist
                this.checkedKeys = checked ? keys : null

                if (this.expandChecked && checked) {
                    this.handleExpandState(list, [keys], true)
                }

                this.handleCheckState(list, keys, !!checked)
            },
            /**
             * 返回半选的 key
             */
            getHalfCheckedKeys() {
                return getAllNodeKeys(this.datalist, 'checkedStatus', halfCheckedStatus, this.packDisabledkey)
            },
            /**
             * 返回未选的 key
             */
            getUncheckedKeys() {
                return getAllNodeKeys(this.datalist, 'checkedStatus', unCheckedStatus, this.packDisabledkey)
            },
            /**
             * 返回已展开的 key
             */
            getExpandedKeys() {
                return getAllNodeKeys(this.datalist, 'expand', true)
            },
            /**
             * 根据key展开/收起
             * @param keys key的数组，或字符串 all
             * @param expand true为展开/false为收起
             */
            setExpandedKeys(keys, expand = true) {
                if (!Array.isArray(keys) && keys !== 'all') {
                    logError('setExpandedKeys 第一个参数非数组，传入的是===>', keys)
                    return
                }
                const list = this.datalist

                // 展开/收起全部
                if (keys === 'all') {
                    list.forEach(k => {
                        k.expand = expand
                        if (k.level > 0) {
                            k.show = expand
                        }
                    })
                    return
                }

                // 收起
                if (expand === false) {
                    const newExpandedKeys = []
                    for (let i = 0; i < this.expandedKeys.length; i++) {
                        const ek = this.expandedKeys[i]
                        if (!keys.includes(ek)) {
                            newExpandedKeys.push(ek)
                        }
                    }
                    this.expandedKeys = [...new Set(newExpandedKeys)]
                    this.handleExpandState(list, keys, false)

                    return
                }

                // 展开
                const newExpandedKeys = []
                for (let i = 0; i < list.length; i++) {
                    if (keys.includes(list[i].key)) {
                        newExpandedKeys.push(list[i].key)
                    }
                }
                this.expandedKeys = [...new Set(newExpandedKeys)]
                this.handleExpandState(list, newExpandedKeys, true)
            },
            /**
             * 返回未展开的 key
             */
            getUnexpandedKeys() {
                return getAllNodeKeys(this.datalist, 'expand', false)
            },
            /**
             * 返回已选的节点
             */
            getCheckedNodes() {
                return getAllNodes(this.datalist, 'checkedStatus', isCheckedStatus, this.packDisabledkey)
            },
            /**
             * 返回半选的节点
             */
            getHalfCheckedNodes() {
                return getAllNodes(this.datalist, 'checkedStatus', halfCheckedStatus, this.packDisabledkey)
            },
            /**
             * 返回未选的节点
             */
            getUncheckedNodes() {
                return getAllNodes(this.datalist, 'checkedStatus', unCheckedStatus, this.packDisabledkey)
            },
            /**
             * 返回已展开的节点
             */
            getExpandedNodes() {
                return getAllNodes(this.datalist, 'expand', true)
            },
            /**
             * 返回未展开的节点
             */
            getUnexpandedNodes() {
                return getAllNodes(this.datalist, 'expand', false)
            },
        },
    }
</script>

<style lang="scss" scoped>
    @font-face {
        font-family: 'da-tree-iconfont';
        /* Project id  */
        src: url('data:application/octet-stream;base64,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') format('truetype');
    }

    .da-tree {
        width: 100%;
        height: 100%;

        &-scroll {
            width: 100%;
            height: 100%;
        }

        &-item {
            display: flex;
            align-items: center;
            height: 0;
            padding: 0;
            overflow: hidden;
            font-size: 28rpx;
            line-height: 1;
            visibility: hidden;
            opacity: 0;
            transition: opacity 0.2s linear;

            &.is-show {
                height: auto;
                padding: 12rpx 24rpx;
                visibility: visible;
                opacity: 1;
            }

            &__icon {
                display: flex;
                align-items: center;
                justify-content: center;
                width: 40rpx;
                height: 40rpx;
                overflow: hidden;

                &--arr {
                    position: relative;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 32rpx;
                    height: 32rpx;

                    &::after {
                        position: relative;
                        z-index: 1;
                        overflow: hidden;
                        /* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */
                        font-family: 'da-tree-iconfont' !important;
                        font-size: 32rpx;
                        font-style: normal;
                        color: #999;
                        -webkit-font-smoothing: antialiased;
                        -moz-osx-font-smoothing: grayscale;
                    }

                    &.is-expand {
                        &::after {
                            content: '\e604';
                        }
                    }

                    &.is-right {
                        transform: rotate(-90deg);
                    }

                    &.is-loading {
                        animation: IconLoading 1s linear 0s infinite;

                        &::after {
                            content: '\e7f1';
                        }
                    }
                }
            }

            &__checkbox {
                width: 40rpx;
                height: 40rpx;
                overflow: hidden;

                &--left {
                    order: 0;
                }

                &--right {
                    order: 1;
                }

                &--icon {
                    position: relative;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 40rpx;
                    height: 40rpx;

                    &::after {
                        position: relative;
                        top: 0;
                        left: 0;
                        z-index: 1;
                        overflow: hidden;
                        /* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */
                        font-family: 'da-tree-iconfont' !important;
                        font-size: 32rpx;
                        font-style: normal;
                        -webkit-font-smoothing: antialiased;
                        -moz-osx-font-smoothing: grayscale;
                    }

                    &.da-tree-checkbox-outline::after {
                        color: #bbb;
                        content: '\ead5';
                    }

                    &.da-tree-checkbox-checked::after {
                        color: var(--theme-color, #007aff);
                        content: '\ead4';
                    }

                    &.da-tree-checkbox-indeterminate::after {
                        color: var(--theme-color, #007aff);
                        content: '\ebce';
                    }

                    &.da-tree-radio-outline::after {
                        color: #bbb;
                        content: '\ecc5';
                    }

                    &.da-tree-radio-checked::after {
                        color: var(--theme-color, #007aff);
                        content: '\ecc4';
                    }

                    &.da-tree-radio-indeterminate::after {
                        color: var(--theme-color, #007aff);
                        content: '\ea4f';
                    }
                }

                &.is--disabled {
                    cursor: not-allowed;
                    opacity: 0.35;
                }
            }

            &__label {
                flex: 1;
                margin-left: 4rpx;
                color: #555;

                &--2 {
                    //选中的颜色
                    // color: var(--theme-color, #007aff); 
                }

                &--append {
                    font-size: 60%;
                    opacity: 0.6;
                }
            }
        }
    }

    @keyframes IconLoading {
        0% {
            transform: rotate(0deg);
        }

        100% {
            transform: rotate(360deg);
        }
    }
</style>